package game.games.graphictest;

import game.Abstract2DMap;
import game.IRenderer;
import game.Position;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;

public abstract class AbstractShape implements IRenderer
{
    private List<Color>   points;
    private List<Integer> exclusivePoints;
    private Position      size;
    private Position      start;
    private int           cellSize = 5;
    
    protected AbstractShape(int width, int height)
    {
        points = new ArrayList<Color>(width * height);
        while (points.size() < width * height)
        {
            points.add(null);
        }
        exclusivePoints = new ArrayList<Integer>();
        size = new Position(width, height);
        start = new Position(0, 0);
        setShape();
    }
    
    protected abstract void setShape();
    
    protected final void setPoint(int x, int y, Color color)
    {
        int index = Abstract2DMap.calculateIndex(x, y, size);
        points.set(index, color);
    }
    
    protected final void setPoints(Position start, Position end, Color color)
    {
        for (int x = start.getX(); x <= end.getX(); x++)
        {
            for (int y = start.getY(); y <= end.getY(); y++)
            {
                setPoint(x, y, color);
            }
        }
    }
    
    protected final void addExclusivePoint(int x, int y)
    {
        int index = Abstract2DMap.calculateIndex(x, y, size);
        exclusivePoints.add(index);
    }
    
    protected final void addExclusivePoints(Position start, Position end)
    {
        for (int x = start.getX(); x <= end.getX(); x++)
        {
            for (int y = start.getY(); y <= end.getY(); y++)
            {
                addExclusivePoint(x, y);
            }
        }
    }
    
    public final Position getSize()
    {
        return size;
    }
    
    public final void setStart(Position start)
    {
        this.start = start;
    }
    
    public final void setCellSize(int cellSize)
    {
        this.cellSize = cellSize;
    }
    
    protected void switchColors(Color from, Color to)
    {
        for (int index = 0; index < points.size();index++)
        {
            Color color = points.get(index);
            if (color == from && exclusivePoints.contains(index) == false)
            {
                points.set(index, to);
            }
        }
    }
    
    @Override
    public final void render(Graphics g)
    {
        for (int index = 0; index < points.size(); index++)
        {
            Color color = points.get(index);
            if (color != null)
            {
                g.setColor(color);
                Position position = Abstract2DMap.calculatePosition(index, size);
                g.fillRect(start.getX() + (position.getX() * cellSize), start.getY() + (position.getY() * cellSize), cellSize, cellSize);
            }
        }
    }
}
